The Victory lets us add charts and data visualization into our React app.
In this article, we’ll look at how to add charts into our React app with Victory.
Transitions
We can set the transition effects for animations with the VictoryBar component.
For instance, we can write:
import React, { useEffect, useState } from "react";
import { VictoryBar, VictoryChart } from "victory";
const random = (min, max) => Math.floor(min + Math.random() * max);
const getData = () => {
const bars = random(6, 10);
return Array(bars)
.fill()
.map((_, index) => {
return {
x: index + 1,
y: random(2, 100)
};
});
};
export default function App() {
const [data, setData] = useState([]);
useEffect(() => {
const timer = setInterval(() => {
setData(getData());
}, 3000);
return () => clearInterval(timer);
}, []);
return (
<VictoryChart domainPadding={{ x: 20 }} animate={{ duration: 500 }}>
<VictoryBar
data={data}
style={{
data: { fill: "tomato", width: 12 }
}}
animate={{
onExit: {
duration: 500,
before: () => ({
_y: 0,
fill: "orange",
label: "BYE"
})
}
}}
/>
</VictoryChart>
);
}
We generate random data for our graph and update it with the new data every 3 seconds.
We set the animate prop on the VictoryBar component to add transition effects for the bars.
onExit.duration has the duration of the leave animation.
We change the color of the bars with fill property.
And the label is displayed when the bars leave the screen.
Brush and Zoom
We can add brush and zoom into our charts with the VictoryChart‘s containerComponent prop.
For instance, we can write:
import React from "react";
import { VictoryChart, VictoryScatter, VictoryZoomContainer } from "victory";
const random = (min, max) => Math.floor(min + Math.random() * max);
const getData = () => {
return Array(50)
.fill()
.map((index) => {
return {
x: random(1, 50),
y: random(10, 90),
size: random(8) + 3
};
});
};
export default function App() {
return (
<VictoryChart
domain={{ y: [0, 100] }}
containerComponent={
<VictoryZoomContainer zoomDomain={{ x: [5, 35], y: [0, 100] }} />
}
>
<VictoryScatter
data={getData()}
style={{
data: {
opacity: ({ datum }) => (datum.y % 5 === 0 ? 1 : 0.7),
fill: ({ datum }) => (datum.y % 5 === 0 ? "tomato" : "black")
}
}}
/>
</VictoryChart>
);
}
We set containerComponent to the VictoryZoomContainer component.
The zoomDomain prop lets us set the zoom level range for the x and y axes with the x and y properties.
We can also create a separate chart for the brush:
import React, { useState } from "react";
import {
VictoryAxis,
VictoryBrushContainer,
VictoryChart,
VictoryLine,
VictoryZoomContainer
} from "victory";
export default function App() {
const [selectedDomain, setSelectedDomain] = useState();
const [zoomDomain, setZoomDomain] = useState();
const handleZoom = (domain) => {
setSelectedDomain(domain);
};
const handleBrush = (domain) => {
setZoomDomain(domain);
};
return (
<>
<VictoryChart
width={550}
height={300}
scale={{ x: "time" }}
containerComponent={
<VictoryZoomContainer
responsive={false}
zoomDimension="x"
zoomDomain={zoomDomain}
onZoomDomainChange={handleZoom}
/>
}
>
<VictoryLine
style={{
data: { stroke: "tomato" }
}}
data={[
{ x: new Date(1982, 1, 1), y: 125 },
{ x: new Date(1987, 1, 1), y: 257 },
{ x: new Date(1993, 1, 1), y: 345 },
{ x: new Date(1997, 1, 1), y: 515 },
{ x: new Date(2001, 1, 1), y: 132 },
{ x: new Date(2005, 1, 1), y: 305 },
{ x: new Date(2011, 1, 1), y: 270 },
{ x: new Date(2015, 1, 1), y: 470 }
]}
/>
</VictoryChart>
<VictoryChart
width={550}
height={90}
scale={{ x: "time" }}
padding={{ top: 0, left: 50, right: 50, bottom: 30 }}
containerComponent={
<VictoryBrushContainer
responsive={false}
brushDimension="x"
brushDomain={selectedDomain}
onBrushDomainChange={handleBrush}
/>
}
>
<VictoryAxis
tickValues={[
new Date(1985, 1, 1),
new Date(1990, 1, 1),
new Date(1995, 1, 1),
new Date(2000, 1, 1),
new Date(2005, 1, 1),
new Date(2010, 1, 1),
new Date(2015, 1, 1)
]}
tickFormat={(x) => new Date(x).getFullYear()}
/>
<VictoryLine
style={{
data: { stroke: "tomato" }
}}
data={[
{ x: new Date(1982, 1, 1), y: 125 },
{ x: new Date(1987, 1, 1), y: 257 },
{ x: new Date(1993, 1, 1), y: 345 },
{ x: new Date(1997, 1, 1), y: 515 },
{ x: new Date(2001, 1, 1), y: 132 },
{ x: new Date(2005, 1, 1), y: 305 },
{ x: new Date(2011, 1, 1), y: 270 },
{ x: new Date(2015, 1, 1), y: 470 }
]}
/>
</VictoryChart>
</>
);
}
We do this by setting the zoomDomain and the selectedDomain by dragging on the bottom graph.
In the bottom VictoryChart , we have the containerComponent set to the VictoryBrushContainer .
brushDomain is set to the selectedDomain ,
And the onBrushDomainChange is set to the handleBrush function to change selectedDomain .
The location will be reflected in the top chart.
We have similar code to set the zoomDomain in the top chart.
The zoom is reflected in the bottom chart.
Conclusion
We can add transitions, brush, and zoom into charts in our React app with Victory.